import { refreshToken } from '@/api/sys/oauth2'
import { getToken, setToken, getRefreshToken } from '@/utils/auth'
import { Notification, MessageBox, Message, Loading } from 'element-ui'
import store from '@/store'
import axios from 'axios'
import qs from 'qs'
import { tansParams, blobValidate } from '@/utils/sdss'
import errorCode from '@/utils/errorCode'
import { saveAs } from 'file-saver'
import router from 'vue-router'
let downloadLoadingInstance

// 是否显示重新登录
export let isRelogin = { show: false }

// 转换请求方式
axios.defaults.transformRequest = [
  function (data) {
    return qs.stringify(data, { allowDots: true })
  },
]
// create an axios instance
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API,
  // withCredentials: true, // send cookies when cross-domain requests
  timeout: 160000, // request timeout
})

// request interceptor
service.interceptors.request.use(
  (config) => {
    // Do something before request is sent
    if (store.getters.token) {
      // 让每个请求携带token-- ['X-Token']为自定义key 请根据实际情况自行修改
      config.headers['access_token'] = getToken()
    }
    return config
  },
  (error) => {
    // Do something with request error
    console.log(error) // for debug
    Promise.reject(error)
  }
)

// response interceptor
service.interceptors.response.use(
  // response => response,
  /**
   * 下面的注释为通过在response里，自定义code来标示请求状态
   * 当code返回如下情况则说明权限有问题，登出并返回到登录页
   * 如想通过 xmlhttprequest 来状态码标识 逻辑可写在下面error中
   * 以下代码均为样例，请结合自生需求加以修改，若不需要，则可删除
   */

  async (response) => {
    // response.setHeader((Referrer - Policy) & quot, value & quot)
    const res = response.data
    if (res.code != null && res.code !== 0) {
      if (res.code === 401) {
        if (!isRelogin.show) {
          isRelogin.show = true

          MessageBox.confirm('登录已过期，请重新登录', '登录超时', {
            confirmButtonText: '重新登录',
            cancelButtonText: '取消',
            type: 'warning',
          })
            .then(() => {
              store.dispatch('user/logout').then(() => {
                location.reload()
              })
            })
            .catch(() => {
              isRelogin.show == false
            })
        }
      } else if (res.code === 200004) {
        const refreshTokenData = getRefreshToken()
        const tokenResponse = await refreshToken(refreshTokenData)
        const data = tokenResponse.data
        store.commit('user/SET_TOKEN', data.access_token)
        setToken(tokenResponse.data.access_token)
        var originalRequest = response.config
        originalRequest._retry = true
        // Do something before request is sent
        if (store.getters.token) {
          // 让每个请求携带token-- ['X-Token']为自定义key 请根据实际情况自行修改
          originalRequest.headers['access_token'] = getToken()
        }
        return axios.request(originalRequest)
      } else if (res.code === 100008 || res.code === 100009) {
        // 请自行在引入 MessageBox
        MessageBox.confirm('你已被登出，可以取消继续留在该页面，或者重新登录', '确定登出', {
          confirmButtonText: '重新登录',
          cancelButtonText: '取消',
          type: 'warning',
        }).then(() => {
          store.dispatch('user/logout').then(() => {
            location.reload() // 为了重新实例化vue-router对象 避免bug
          })
        })
      }
    }
    return Promise.resolve(response)
  },
  (error) => {
    let errorMsg
    if (error.response && error.response.data && error.response.data.msg) {
      errorMsg = error.response.data.msg
    } else {
      errorMsg = '接口请求出错'
    }

    return Promise.reject(error)
  }
)
// 通用下载方法
export function download(url, params, type, filename, config) {
  downloadLoadingInstance = Loading.service({ text: '正在下载数据，请稍候', spinner: 'el-icon-loading', background: 'rgba(0, 0, 0, 0.7)' })
  if (type == 'post') {
    return service
      .post(url, params, {
        transformRequest: [
          (params) => {
            return tansParams(params)
          },
        ],
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        responseType: 'blob',
        ...config,
      })
      .then(async (data) => {
        const isBlob = blobValidate(data.data)
        if (isBlob) {
          const blob = new Blob([data.data])
          saveAs(blob, filename)
        } else {
          const resText = await data.text()
          const rspObj = JSON.parse(resText)
          const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
          Message.error(errMsg)
        }
        downloadLoadingInstance.close()
      })
      .catch((r) => {
        console.error(r)
        Message.error('下载文件出现错误，请联系管理员！')
        downloadLoadingInstance.close()
      })
  } else {
    const queryString = tansParams(params)

    // Remove trailing '&' if present
    const trimmedQueryString = queryString.endsWith('&') ? queryString.slice(0, -1) : queryString

    // Split the string by '&' to get key-value pairs
    const keyValuePairs = trimmedQueryString.split('&')

    // Initialize an empty object to store the result
    const result = {}

    // Iterate over each key-value pair and add it to the object
    keyValuePairs.forEach((pair) => {
      const [key, value] = pair.split('=')
      result[key] = value
    })

    return service
      .get(url, {
        params: result, // Convert params to query string
        responseType: 'blob', // Set response type to blob
        ...config,
      })
      .then(async (response) => {
        const isBlob = blobValidate(response.data)
        console.log(isBlob);
        if (isBlob) {
          const blob = new Blob([response.data])
          saveAs(blob, filename) // Download the blob as a file
        } else {
          const resText = await response.text()
          const rspObj = JSON.parse(resText)
          const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
          Message.error(errMsg)
        }
        downloadLoadingInstance.close()
      })
      .catch((error) => {
        console.error(error)
        Message.error('下载文件出现错误，请联系管理员！')
        downloadLoadingInstance.close()
      })
  }
}

export default service
